package world.snowcrystal.manager;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
import world.snowcrystal.common.ErrorCode;
import world.snowcrystal.datasource.*;
import world.snowcrystal.exception.BusinessException;
import world.snowcrystal.exception.ThrowUtils;
import world.snowcrystal.model.dto.search.SearchRequest;
import world.snowcrystal.model.entity.Picture;
import world.snowcrystal.model.enums.SearchTypeEnum;
import world.snowcrystal.model.vo.PostVO;
import world.snowcrystal.model.vo.SearchVO;
import world.snowcrystal.model.vo.UserVO;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.CompletableFuture;

/**
 * 搜索门面
 */
@Component
@Slf4j
public class SearchFacade {

    @Resource
    private EsPostDataSource esPostDataSource;

    @Resource
    private SqlUserDataSource sqlUserDataSource;

    @Resource
    private PictureDataSource pictureDataSource;

    @Resource
    private DataSourceRegistry dataSourceRegistry;


    private <T> CompletableFuture<Page<T>> search(DataSource<T> ds, String searchText, long pageNum, long pageSize,HttpServletRequest request) {
        return CompletableFuture.supplyAsync(() -> ds.doSearch(searchText, pageNum, pageSize,request));
    }

    public Page<PostVO> searchPost(@RequestBody SearchRequest searchRequest,
                                   HttpServletRequest request) {
        try {
            return search(esPostDataSource, searchRequest.getSearchText(),
                    searchRequest.getCurrent(), searchRequest.getPageSize(),request).get();
        } catch (Exception e) {
            log.error("查询异常", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "查询异常");
        }
    }

    public SearchVO searchAll(@RequestBody SearchRequest searchRequest, HttpServletRequest request) {
        String type = searchRequest.getType();
        ThrowUtils.throwIf(StringUtils.isBlank(type), ErrorCode.PARAMS_ERROR);
        SearchTypeEnum searchTypeEnum = SearchTypeEnum.getEnumByValue(type);
        String searchText = searchRequest.getSearchText();
        long current = searchRequest.getCurrent();
        long pageSize = searchRequest.getPageSize();
        // 搜索出所有数据
        if (searchTypeEnum == SearchTypeEnum.ALL) {

            CompletableFuture<Page<UserVO>> userTask = search(sqlUserDataSource, searchText, current, pageSize,request);

            CompletableFuture<Page<PostVO>> postTask = search(esPostDataSource, searchText, current, pageSize,request);

            CompletableFuture<Page<Picture>> pictureTask = search(pictureDataSource, searchText, current, pageSize,request);

            CompletableFuture.allOf(userTask, postTask, pictureTask).join();
            try {
                Page<UserVO> userVOPage = userTask.get();
                Page<PostVO> postVOPage = postTask.get();
                Page<Picture> picturePage = pictureTask.get();
                SearchVO searchVO = new SearchVO();
                searchVO.setUserList(userVOPage.getRecords());
                searchVO.setPostList(postVOPage.getRecords());
                searchVO.setPictureList(picturePage.getRecords());
                return searchVO;
            } catch (Exception e) {
                log.error("查询异常", e);
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "查询异常");
            }
        } else {
            SearchVO searchVO = new SearchVO();
            DataSource<?> dataSource = dataSourceRegistry.getDataSourceByType(type);
            Page<?> page = dataSource.doSearch(searchText, current, pageSize,request);
            searchVO.setDataList(page.getRecords());
            return searchVO;
        }
    }
}
